<!-- Copyright 2013 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// -->
<!DOCTYPE html>
<title>Unit Test of e2e.signer.DSA</title>
<script src="../../../closure/base.js"></script>
<script src="test_js_deps-runfiles.js"></script>
<script>
  goog.require('e2e.BigNum');
  goog.require('e2e.hash.all');
  goog.require('e2e.signer.Algorithm');
  goog.require('e2e.signer.DSA');
  goog.require('e2e.signer.DSA.testData');
  goog.require('e2e.random');
  goog.require('goog.testing.jsunit');
</script>
<script>
/**
 * Tests DSA with public test vectors downloaded from NIST.
 */
function testWithNISTVectors() {
  goog.array.forEach(e2e.signer.DSA.testData.NISTVectors,
      function(vector) {
        var key = {
            'p': vector['P'],
            'q': vector['Q'],
            'g': vector['G'],
            'x': vector['X'],
            'y': vector['Y']};
        var dsa = new e2e.signer.DSA(
            e2e.signer.Algorithm.DSA, key);

        // Test consistency
        for (var i = 0; i < 10; i++) {
          var m = e2e.random.getRandomBytes(20);
          assertTrue(e2e.async.Result.getValue(dsa.verify(m,
              e2e.async.Result.getValue(dsa.sign(m)))));
        }

        var sig = {
          'r': vector['R'],
          's': vector['S']
        };
        assertTrue(e2e.async.Result.getValue(dsa.verify(vector['M'], sig)));
        var nonce = new e2e.BigNum(vector['K']);
        var sigPrime = e2e.async.Result.getValue(
            dsa.signForTestingOnly(vector['M'], nonce));
        assertArrayEquals(sig['r'], sigPrime['r']);
        assertArrayEquals(sig['s'], sigPrime['s']);
  });
}


/**
 * Tests that invalid signatures are rejected.
 */
function testInvalidSignature() {
  var vector = e2e.signer.DSA.testData.NISTVectors[0];
  var key = {
      'p': vector['P'],
      'q': vector['Q'],
      'g': vector['G'],
      'x': vector['X'],
      'y': vector['Y']};
  var dsa = new e2e.signer.DSA(
      e2e.signer.Algorithm.DSA, key);
  var m = [0x00];
  var sig = {
    'r': e2e.BigNum.ZERO.toByteArray(),
    's': e2e.BigNum.ONE.toByteArray()
  };
  assertFalse('r should be bigger than 0.',
      e2e.async.Result.getValue(dsa.verify(m, sig)));
  sig = {
    'r': vector['Q'],
    's': e2e.BigNum.ONE.toByteArray()
  };
  assertFalse('r should be less than Q.',
      e2e.async.Result.getValue(dsa.verify(m, sig)));

  sig = {
    's': e2e.BigNum.ZERO.toByteArray(),
    'r': e2e.BigNum.ONE.toByteArray()
  };
  assertFalse('s should be bigger than 0.',
      e2e.async.Result.getValue(dsa.verify(m, sig)));
  sig = {
    's': vector['Q'],
    'r': e2e.BigNum.ONE.toByteArray()
  };
  assertFalse('s should be less than Q.',
      e2e.async.Result.getValue(dsa.verify(m, sig)));
}
</script>
